using System;
using FireStarterModeller.BO;
using FireStarterModeller.Test.BO;
using FireStarterModeller.UI;
using Habanero.Base;
using Habanero.Faces.Base;
using Habanero.Faces.Win;
using NUnit.Framework;

namespace FireStarterModeller.Test.UI
{
    [TestFixture]
    public class TestDMUniqueConstraintPropertiesControl
    {
        [TestFixtureSetUp]
        public void SetupFixture()
        {
            UITestUtils.SetupFixture();
        }

        [SetUp]
        public virtual void SetupTest()
        {
            UITestUtils.SetupTest();
        }

        private static void AssertColumnComboBoxItemsCount
            (int expectedItemCount, DMUniqueConstraintPropertiesControl actualControl, string columnName)
        {
            IDataGridViewColumn column = actualControl.SelectorAndBOEditorControl.Grid.Columns[columnName];
            IDataGridViewComboBoxColumn comboBoxColumn = (IDataGridViewComboBoxColumn) column;
            Assert.IsNotNull(comboBoxColumn.DataSource);
            Assert.AreEqual
                (expectedItemCount, comboBoxColumn.Items.Count,
                 "Count of the items in the combo box column was expected to be " + expectedItemCount);
        }

        private static IGridControl GetGridControl(DMUniqueConstraintPropertiesControl control)
        {
            return (IGridControl) control.Controls[0].Controls[0];
        }

        private static DMUniqueConstraintPropertiesControl GetUniqueConstraintControlWithClassWithTwoProps
            (out DMUniqueConstraint uniqueConstraint)
        {
            TestUtilsDMProperty.CreateSavedDMProperty();
            TestUtilsDMProperty.CreateSavedDMProperty();
            uniqueConstraint = TestUtilsShared.CreateSavedUniqueConstraintInfoWithUniqueConstraintProperties();
            return new DMUniqueConstraintPropertiesControl(new ControlFactoryWin());
        }

        [Test]
        public void Test_Construction_NullControlFactory_ShouldRaiseError()
        {
            //---------------Set up test pack-------------------

            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            try
            {
                new DMUniqueConstraintPropertiesControl(null);
                Assert.Fail("expected ArgumentNullException");
            }
                //---------------Test Result -----------------------
            catch (ArgumentNullException ex)
            {
                StringAssert.Contains("Value cannot be null", ex.Message);
                StringAssert.Contains("", ex.ParamName);
            }
        }

        [Test]
        public void TestConstruction()
        {
            //---------------Set up test pack-------------------
            const string columnName = "PropertyID";
            //-------------Assert Preconditions -------------

            //---------------Execute Test ----------------------
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            //---------------Test Result -----------------------
            Assert.IsInstanceOf(typeof (UserControlWin), control);
            Assert.IsInstanceOf(typeof (IFormControl), control);
            Assert.AreEqual(1, control.Controls.Count);
            Assert.IsInstanceOf(typeof (IGridControl), GetGridControl(control));
            IGridControl gridControl = GetGridControl(control);
            Assert.IsFalse(gridControl.FilterControl.Visible);
            IGridBase grid = control.SelectorAndBOEditorControl.Grid;
            Assert.GreaterOrEqual(grid.ColumnCount, 0, "There should be columns set up");
            Assert.IsTrue(grid.Columns.Contains(columnName));
            IDataGridViewColumn column = grid.Columns[columnName];
            Assert.IsInstanceOf(typeof (IDataGridViewComboBoxColumn), column);
            IButtonGroupControl buttons = gridControl.Buttons;
            Assert.AreEqual(3, buttons.Controls.Count);
            Assert.IsNotNull(buttons["Save"]);
            Assert.IsNotNull(buttons["Cancel"]);
            Assert.IsNotNull(buttons["Edit"]);
            Assert.IsFalse(buttons["Save"].Visible);
        }

        [Test]
        public void TestSetUniqueConstraint_LoadsUniqueConstraintPropertyInfos()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint uniqueConstraint =
                TestUtilsShared.CreateSavedUniqueConstraintInfoWithUniqueConstraintProperties();
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            IGridControl gridAndBOEditorControl = GetGridControl(control);
            //---------------Assert Precondition----------------
            Assert.GreaterOrEqual(uniqueConstraint.UniqueConstraintProperties.Count, 1);
            //---------------Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //---------------Test Result -----------------------
            Assert.AreSame(uniqueConstraint, control.UniqueConstraint);
            Assert.AreSame(uniqueConstraint, control.BusinessObject);
            IBusinessObjectCollection boCollection = gridAndBOEditorControl.BusinessObjectCollection;
            Assert.AreSame(boCollection, uniqueConstraint.UniqueConstraintProperties);
            Assert.AreSame(boCollection, control.BusinessObjectCollection);
            Assert.AreEqual(boCollection.Count, uniqueConstraint.UniqueConstraintProperties.Count);
        }

        [Test]
        public void TestSetUniqueConstraint_ToNull_LoadsEmptyCollection()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            control.UniqueConstraint = null;
            //---------------Test Result -----------------------
            Assert.IsNull(control.UniqueConstraint);
            Assert.IsNull(control.BusinessObject);
            Assert.AreEqual(0, control.BusinessObjectCollection.Count);
        }

        [Test]
        public void TestSetBusinessObject_LoadsUniqueConstraintPropertyInfos()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint uniqueConstraint =
                TestUtilsShared.CreateSavedUniqueConstraintInfoWithUniqueConstraintProperties();
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            IGridControl gridAndBOEditorControl = GetGridControl(control);
            //---------------Assert Precondition----------------
            Assert.GreaterOrEqual(uniqueConstraint.UniqueConstraintProperties.Count, 1);
            //---------------Execute Test ----------------------
            control.BusinessObject = uniqueConstraint;
            //---------------Test Result -----------------------
            Assert.AreSame(uniqueConstraint, control.UniqueConstraint);
            Assert.AreSame(uniqueConstraint, control.BusinessObject);
            IBusinessObjectCollection boCollection = gridAndBOEditorControl.BusinessObjectCollection;
            Assert.AreSame(boCollection, uniqueConstraint.UniqueConstraintProperties);
            Assert.AreSame(boCollection, control.BusinessObjectCollection);
            Assert.AreEqual(boCollection.Count, uniqueConstraint.UniqueConstraintProperties.Count);
        }

        [Test]
        public void TestSetBusinessObject_ToNull_LoadsEmptyCollection()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            //---------------Assert Precondition----------------

            //---------------Execute Test ----------------------
            control.BusinessObject = null;
            //---------------Test Result -----------------------
            Assert.IsNull(control.BusinessObject);
            Assert.IsNull(control.UniqueConstraint);
            Assert.AreEqual(0, control.BusinessObjectCollection.Count);
        }

        [Test]
        public void TestDisabledAtCreation()
        {
            //---------------Execute Test ----------------------
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            //---------------Test Result -----------------------

            Assert.IsFalse(control.Enabled);
        }

        [Test]
        public void TestSetBusinessObject_EnablesControl()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint dmUniqueConstraint =
                TestUtilsShared.CreateSavedUniqueConstraintInfoWithUniqueConstraintProperties();
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());

            //---------------Execute Test ----------------------
            control.UniqueConstraint = dmUniqueConstraint;
            //---------------Test Result -----------------------
            Assert.IsTrue(control.Enabled);
        }

        [Test]
        public void TestSetBusinessObject_ToNull_DisablesControl()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint info = TestUtilsShared.CreateSavedUniqueConstraintInfoWithUniqueConstraintProperties();
            DMUniqueConstraintPropertiesControl control = new DMUniqueConstraintPropertiesControl
                (new ControlFactoryWin());
            control.UniqueConstraint = info;
            //---------------Execute Test ----------------------
            control.UniqueConstraint = null;
            //---------------Test Result -----------------------
            Assert.IsFalse(control.Enabled);
        }

        [Test]
        public void
            Test_UniqueConstraint_SetsUpOwnerColumnLookupItems_WhenNotNullUniqueConstraint_ShouldHaveAllOwnerProps()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint uniqueConstraint;
            DMUniqueConstraintPropertiesControl control = GetUniqueConstraintControlWithClassWithTwoProps
                (out uniqueConstraint);
            //---------------Assert Precondition----------------
            Assert.IsNull(control.UniqueConstraint);
            Assert.IsNotNull(uniqueConstraint.Class);
            Assert.AreEqual(2, uniqueConstraint.Class.Properties.Count);
            //---------------Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint;
            //---------------Test Result -----------------------
            AssertColumnComboBoxItemsCount(2, control, "PropertyID");
        }

        [Test]
        public void Test_UniqueConstraint_SetsUpOwnerColumnLookupItems_WhenNullUniqueConstraint_ShouldHaveNoItems()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint uniqueConstraint;
            DMUniqueConstraintPropertiesControl control = GetUniqueConstraintControlWithClassWithTwoProps
                (out uniqueConstraint);
            control.UniqueConstraint = uniqueConstraint;
            //---------------Assert Precondition----------------
            AssertColumnComboBoxItemsCount(2, control, "PropertyID");
            //---------------Execute Test ----------------------
            control.UniqueConstraint = null;
            //---------------Test Result -----------------------
            AssertColumnComboBoxItemsCount(0, control, "PropertyID");
        }

        [Test]
        public void
            Test_UniqueConstraint_SetsUpOwnerColumnLookupItems_WhenUniqueConstraintWithNullOwner_ShouldHaveNoItems()
        {
            //---------------Set up test pack-------------------
            DMUniqueConstraint uniqueConstraint;
            DMUniqueConstraintPropertiesControl control = GetUniqueConstraintControlWithClassWithTwoProps
                (out uniqueConstraint);
            DMUniqueConstraint uniqueConstraint2 = TestUtilsDMUniqueConstraint.CreateUnsavedDefaultDMUniqueConstraint();
            control.UniqueConstraint = uniqueConstraint;
            //---------------Assert Precondition----------------
            Assert.IsNull(uniqueConstraint2.Class);
            AssertColumnComboBoxItemsCount(2, control, "PropertyID");
            //---------------Execute Test ----------------------
            control.UniqueConstraint = uniqueConstraint2;
            //---------------Test Result -----------------------
            AssertColumnComboBoxItemsCount(0, control, "PropertyID");
        }
    }
}